package com.ia.aistream.manager.framework.filter;

import com.alibaba.fastjson.JSON;
import com.ia.aistream.common.constant.Constants;
import com.ia.aistream.common.core.domain.AjaxResult;
import com.ia.aistream.common.enums.ResponeCodeMsgEnums;
import com.ia.aistream.common.utils.ServletUtils;
import com.ia.aistream.manager.authen.ITokenManager;
import com.ia.aistream.manager.framework.config.properties.ShiroConf;
import com.ia.aistream.mapper.system.SysUserMapper;
import com.ia.aistream.model.system.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.Optional;

/**
 * token验证基础类
 *
 * @author chenjunsheng
 */
@Slf4j
public abstract class BaseTokenFilter extends AccessControlFilter {
    @Autowired
    private ShiroConf shiroConf;

    @Autowired
    private ITokenManager tokenManager;

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse response, Object mappedValue) throws Exception {
        HttpServletRequest request = ((HttpServletRequest) servletRequest);
        SysUser user = (SysUser) request.getAttribute(Constants.USER_ATTR_KEY);
        if (user != null) {
            return true;
        }

        String token = this.getToken(request);
        if (StringUtils.isBlank(token)) {
            return false;
        }

        try {
            user = tokenManager.getTokenUser(token);
        } catch (Exception e) {
            log.error("[ 令牌验证 ]令牌已过期过期，令牌:>{}，异常:>", token, e);
            return false;
        }

        if (user == null) {
            return false;
        }

        request.setAttribute(Constants.USER_ATTR_KEY, user);
        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        Optional<String> optional = this.appliedPaths.keySet().stream().filter(path -> super.pathsMatch(path, request)).findFirst();
        if (optional.isPresent()) {
            String filters = shiroConf.getFilterChainDefinitionMap().get(optional.get());
            String[] filterArr = StringUtils.split(filters, ",");
            for (int i = 0; i < filterArr.length; i++) {
                // 说明这个拦截器之后还有其他拦截器，所以返回true，进入下一个拦截器进行校验
                System.out.println("name="+getName()+"-----attr="+filterArr[i]);
                if (Objects.equals(filterArr[i], getName()) && i < filterArr.length - 1) {
                    return true;
                }
            }
        }
        AjaxResult result = AjaxResult.error(ResponeCodeMsgEnums.NO_AUTHORITY.getErrcode(), ResponeCodeMsgEnums.NO_AUTHORITY.getErrmsg(),null);
        ServletUtils.renderString((HttpServletResponse) response, JSON.toJSONString(result));
        return false;
    }

    /**
     * 获取token 的方法
     *
     * @param request
     * @return
     */
    protected abstract String getToken(HttpServletRequest request);
}
